package com.zhiyun.hxzy.aop;

import com.zhiyun.hxzy.dao.ProgrammerDao;
import com.zhiyun.hxzy.domain.ErrorLog;
import com.zhiyun.hxzy.domain.Log;
import com.zhiyun.hxzy.domain.Programmer;
import com.zhiyun.hxzy.service.ErrorLogService;
import com.zhiyun.hxzy.service.LogService;
import com.zhiyun.hxzy.service.ProgrammerService;
import com.zhiyun.hxzy.util.MailUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayOutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Date;
import java.util.List;

@Component
@Aspect
public class LogAop {
    @Autowired
    private LogService logService;
    @Autowired
    private ErrorLogService errorLogService;
    @Autowired
    private HttpServletRequest request;
    private Date visitTime;
    @Autowired
    private MailUtil mailUtil;
    @Autowired
    private ProgrammerService programmerService;

    @Before("execution(* com.zhiyun.hxzy.controller.admin.*.*(..))")
    public void qianzhi() {
        visitTime = new Date();
    }

    @AfterReturning("execution(* com.zhiyun.hxzy.controller.admin.*.*(..))")
    public void houzhi(JoinPoint joinPoint) {
        SecurityContext context = SecurityContextHolder.getContext(); // 获取到Security容器
        User user = (User) context.getAuthentication().getPrincipal();

        String requestURI = request.getRequestURI();//访问路径
        String localAddr = request.getLocalAddr();//访问ip
        long l = new Date().getTime() - visitTime.getTime();//访问时长
        String name = joinPoint.getSignature().getName();//访问方法

        Log log = new Log();
        log.setUsername(user.getUsername());
        log.setVisitTime(visitTime);
        log.setExecutionTime(l);
        log.setIp(localAddr);
        log.setUrl(requestURI);
        log.setMethod(name);
        logService.logAdd(log);
    }

    @AfterThrowing(throwing = "ex",pointcut = "execution(* com.zhiyun.hxzy.controller.admin.*.*(..))")
    public void yichang(JoinPoint joinPoint, Throwable ex) {
        SecurityContext context = SecurityContextHolder.getContext(); // 获取到Security容器
        User user = (User) context.getAuthentication().getPrincipal();
        // 获取异常栈信息
        ByteArrayOutputStream buf = new ByteArrayOutputStream();
        ex.printStackTrace(new java.io.PrintWriter(buf, true));
        String expMessage = buf.toString();//异常栈信息
        String requestURI = request.getRequestURI();//访问路径
        String localAddr = request.getLocalAddr();//访问ip
        String name = joinPoint.getSignature().getName();//访问方法
        String message = ex.getMessage();
        ErrorLog log = new ErrorLog();
        log.setUsername(user.getUsername());
        log.setVisitTime(visitTime);
        log.setIp(localAddr);
        log.setUrl(requestURI);
        log.setMethod(name);
        log.setMessage(message);
        log.setStackTrace(expMessage);
        errorLogService.addErrorLog(log);


        // 给程序员发送邮件：异常信息邮件
        String text = "出异常了！：" +
                "<br>异常信息:" + ex.getMessage() +
                "<br>异常栈信息:" + expMessage;

        // 发送邮件
        new Thread(new Runnable() {
            @Override
            public void run() {
                List<Programmer> programmers = programmerService.findAllActiveProgrammer();
                for (Programmer programmer:programmers){
                    mailUtil.sendMail(programmer.getPemail(),text,"智云系统出异常了!");
                }
            }
        }).start();
    }
}
